namespace FIREFLYX {
    /** 辐照度卷积 （普通cubemap 渲染到 辐照度的cubemap） 着色器*/
    export const BUILTIN_SHADER_IRRADIANCE_CONVOLUTION = `irradianceConvolution`;
    DefaultAsset.shaderGenMap[BUILTIN_SHADER_IRRADIANCE_CONVOLUTION] = () => {
        const vsCode = `#version 300 es
            precision highp float;
            precision highp int;
            layout (location = 0) in vec4 a_Position; //顶点 位置 是有默认值的 (0,0,0,1)
            
            out vec3 v_wroldPosition;
            mat4 u_projectMtx;                  //投影矩阵,硬编码一个
            mat4 u_viewMtx;                     //视窗矩阵,硬编码一个
            void main() {
                // vec4 pos = vec4(a_Position.xyz , 1.0);
                v_wroldPosition = a_Position.xyz;
                gl_Position = u_projectMtx * u_viewMtx * vec4(WorldPos, 1.0);
            }
        `;

        const fsCode = `#version 300 es
            precision highp float;
            precision highp int;

            uniform samplerCube u_skybox;

            uniform ubo_cam_block{
                mat4 u_viewMtx;                     //视窗矩阵
                mat4 u_projectMtx;                  //投影矩阵
                vec4 u_eyePos;                      //眼睛位置
            } uboCam;

            #define ViewMatrix uboCam.u_viewMtx
            #define ProjectMatrix uboCam.u_projectMtx
            #define SkyBoxTex u_skybox

            float _RadicalInverse_VdC(uint bits) {
                // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
                // efficient VanDerCorpus calculation.
            
                bits = (bits << 16u) | (bits >> 16u);
                bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
                bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
                bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
                bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
                return float(bits) * 2.3283064365386963e-10; // / 0x100000000
            }
    
            vec2 Hammersley(uint i, uint N) {
                return vec2(float(i) / float(N), _RadicalInverse_VdC(i));
            }

            in vec4 v_position;
            out vec4 color;
            void main(){
                vec3 N = normalize(WorldPos);

                vec3 irradiance = vec3(0.0);
                
                const uint SAMPLE_NUM = 4096u;
                for(uint i=0u;i<SAMPLE_NUM;i++) {
                    vec2 Xi = Hammersley(i, SAMPLE_NUM);
                    vec3 L = CosOnHalfSphere(Xi, N);
                    irradiance += texture(environmentMap, L).xyz;
                }
                
                irradiance *= 1.0 / float(SAMPLE_NUM);
                color = vec4(irradiance , 1.0);
            }
        `;
        //glsl
        const vs = new GLSL();
        vs.setCode(vsCode);
        const fs = new GLSL();
        fs.setCode(fsCode);

        //shader
        let result: Shader = new Shader();
        result.tag = BUILTIN_SHADER_IRRADIANCE_CONVOLUTION;
        result.lightMode = RenderPipeline.LM_FORWARD;
        result.vertexGLSL = vs;
        result.fragmentGLSL = fs;
        //unifrom 默认值
        result.definePropertyMap = {};
        //
        result.definePropertyMap.u_mainTex = {
            type: "texture",
            value: "white"
        };

        //apply
        result.apply();

        return result;
    };
}